import {
  Product3DGroup,
  AssemblyProductGroup,
  Sub3DGroup,
  Base3DGroup
} from "../types/DrawingGroups/groups";
import { Object3D, type Object3DEventMap } from "three";
import type { KujialeParamModel } from "../types/KujialeJsonModels/KujialeParamModel";

export function TraverseAndFilter(
  children: Object3D<Object3DEventMap>[],
  fnPredict: (curModel: KujialeParamModel) => boolean, //判定条件，过滤并加入
  fnFilter: (curModel: KujialeParamModel) => boolean, //判定条件，过滤但不加入
  fnAction: (curGroup: Base3DGroup) => void, //对成功过滤的模型的操作
  fnActionOnOthers: (
    curGroup: Base3DGroup,
    curModel: KujialeParamModel | undefined
  ) => void //执行操作，对非过滤的操作
): Base3DGroup[] {
  const groups: Base3DGroup[] = [];

  const filterMethod = (currentGroup: Base3DGroup, result: Base3DGroup[]) => {
    var models = currentGroup.model.kujialeModel;
    var foundit = false;
    if (models && models.length == 1) {
      //不需要考虑组合产品的情况，因为是重复的
      models.forEach((it) => {
        if (fnFilter(it)) {
          foundit = true;
        } else if (fnPredict(it)) {
          fnAction(currentGroup);
          result.push(currentGroup);
          foundit = true;
        } else {
          fnActionOnOthers(currentGroup, it);
        }
      });
    } else {
      fnActionOnOthers(currentGroup, undefined); //assembly product
    }

    if (!foundit) {
      currentGroup.children
        .filter((it) => it instanceof Base3DGroup)
        .forEach((cg) => filterMethod(cg, result));
    }
  };

  children
    .filter((g) => g instanceof Base3DGroup)
    .forEach((g) => filterMethod(g, groups));

  return groups;
}
